using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Reflection;
using GadgetBase;


namespace Sidebar
{

    public partial class SidebarPanel : System.Windows.Window
    {
        private const string gadgetDirectory = @"Gadgets";

        private WindowInteropHelper wih;
        private DockMode mode;
        private bool active = false;
        private DoubleAnimation activateAnimation;
        private DoubleAnimation disableAnimation;
        private Grid grid;
        private Image borderImage = new Image();
        private Image backgroundImage = new Image();
        private DockCollection dock;
        private GadgetCollection gadgets = new GadgetCollection();
        private GadgetWindow dragEntered = null;

        private AddGadgetWindow addGadgetWindow = new AddGadgetWindow();

        public bool Active
        {
            get
            {
                return active;
            }
            set
            {
                active = value;
                this.borderImage.BeginAnimation(Image.OpacityProperty, (active ? activateAnimation : disableAnimation));
            }
        }
        public DockMode Dock
        {
            get
            {
                return mode;
            }
            set
            {
                mode = value;
                UpdateLocation();
            }
        }
        public IntPtr Handle
        {
            get
            {
                return wih.Handle;
            }
        }

        public new double Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                base.Width = value;
                UpdateLocation();
            }
        }

        private event GadgetWindowEventHandler3 GadgetDragEnter;
        private event GadgetWindowEventHandler3 GadgetDragLeave;
        private event GadgetWindowEventHandler3 GadgetDragOver;

        public SidebarPanel()
        {
            this.wih = new WindowInteropHelper(this);
            this.dock = new DockCollection(this);

            string localPath = UsefulMethods.getTileDllPath();

            InitializeComponent();

            this.gadgets.CollectionChanged += new NotifyCollectionChangedEventHandler(gadgets_CollectionChanged);            

            this.borderImage.Source = GetBitmapImage(@"Border2.png");
            this.borderImage.HorizontalAlignment = HorizontalAlignment.Left;
            this.borderImage.VerticalAlignment = VerticalAlignment.Stretch;
            this.borderImage.Stretch = Stretch.None;
            this.borderImage.Opacity = 0;

            this.backgroundImage.Source = GetBitmapImage(@"bg.png");
            this.backgroundImage.HorizontalAlignment = HorizontalAlignment.Stretch;
            this.backgroundImage.VerticalAlignment = VerticalAlignment.Stretch;
            this.backgroundImage.Stretch = Stretch.Fill;
            this.backgroundImage.Opacity = 1;

            this.grid = this.Content as Grid;
            this.grid.Children.Insert(0, this.borderImage);
            this.grid.Children.Insert(0, this.backgroundImage);

            this.activateAnimation = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(0.5), FillBehavior.HoldEnd);
            this.disableAnimation = new DoubleAnimation(1, 0, TimeSpan.FromSeconds(0.7), FillBehavior.HoldEnd);

            this.AllowsTransparency = true;
            this.Background = new SolidColorBrush(Colors.Transparent);
            this.Dock = DockMode.Right;
            this.ShowInTaskbar = false;
            this.SnapsToDevicePixels = true;            
            this.Width = 150;
            this.GadgetDragEnter += new GadgetWindowEventHandler3(this_GadgetDragEnter);
            this.GadgetDragLeave += new GadgetWindowEventHandler3(this_GadgetDragLeave);
            this.GadgetDragOver += new GadgetWindowEventHandler3(this_GadgetDragOver);
            this.MouseLeftButtonDown += new MouseButtonEventHandler(Window_MouseDown);
            this.MouseMove += new MouseEventHandler(Window1_MouseMove);
            this.MouseEnter += new MouseEventHandler(Window1_MouseEnter);
            this.MouseLeave += new MouseEventHandler(Window1_MouseLeave);
            this.Closing += new CancelEventHandler(Window1_Closing);
            this.Loaded += new RoutedEventHandler(Window1_Loaded);            
        }

        public bool IsDragOver(GadgetWindow gadget)
        {
            return this.RestoreBounds.IntersectsWith(gadget.RestoreBounds);
        }

        private void CloseChildWindows()
        {
            foreach (GadgetWindow gadget in this.gadgets)
            {
                if (gadget != null && gadget.IsVisible)
                {
                    gadget.Close();
                }
            }
        }
        private void RegisterGadget(GadgetWindow gadget)
        {
            gadget.BeginDrag += new GadgetWindowEventHandler3(Gadget_BeginDrag);
            gadget.Drop += new GadgetWindowEventHandler3(Gadget_Drop);
            gadget.LocationChanged += new EventHandler(Gadget_LocationChanged);
            //dock.Add(gadget); //!!
            gadget.Show();
        }
        private void ShowChildWindows()
        {
            LoadGadgets();
        }
        private void UnregisterGadget(GadgetWindow gadget)
        {
            gadget.Close();
            gadget.Drop -= new GadgetWindowEventHandler3(Gadget_Drop);
            gadget.LocationChanged -= new EventHandler(Gadget_LocationChanged);
            if (dock.Contains(gadget))
            {
                dock.Remove(gadget);
            }
        }
        private void UpdateLocation()
        {
            if (Dock == DockMode.Right)
            {
                this.Left = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Right - this.Width;
            }
            else
            {
                this.Left = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Left;
            }
            this.Top = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Top;
            this.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
        }

        private void LoadGadgets()
        {
            GadgetWindow[] gadgets = ModuleManager.SearchGadgets(gadgetDirectory);

            foreach (GadgetWindow gadget in gadgets)
            {
                this.gadgets.Add(gadget);
            }
        }

        private void Gadget_BeginDrag(GadgetWindow sender)
        {
            this.dock.Remove(sender);
        }
        private void Gadget_Drop(GadgetWindow sender)
        {
            if (IsDragOver(sender))
            {
                OnGadgetDrop(sender);
            }
        }
        private void Gadget_LocationChanged(object sender, EventArgs e)
        {
            GadgetWindow gadget = sender as GadgetWindow;
            if (gadget.IsDraging)
            {
                if (IsDragOver(gadget))
                {
                    if (this.dragEntered == null)
                    {
                        this.dragEntered = gadget;
                        OnGadgetDragEnter(this.dragEntered);
                    }
                    OnGadgetDragOver(gadget);
                }
                else
                {
                    if (this.dragEntered != null)
                    {
                        OnGadgetDragLeave(this.dragEntered);
                        this.dragEntered = null;
                    }
                }
            }
        }
        private void gadgets_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    {
                        foreach (GadgetWindow gadget in e.NewItems)
                        {
                            RegisterGadget(gadget);
                        }
                        break;
                    }
                case NotifyCollectionChangedAction.Replace:
                    {
                        foreach (GadgetWindow gadget in e.NewItems)
                        {
                            RegisterGadget(gadget);
                        }

                        foreach (GadgetWindow gadget in e.OldItems)
                        {
                            UnregisterGadget(gadget);
                        }

                        break;
                    }
                case NotifyCollectionChangedAction.Reset:
                case NotifyCollectionChangedAction.Remove:
                    {
                        foreach (GadgetWindow gadget in e.OldItems)
                        {
                            UnregisterGadget(gadget);
                        }
                        break;
                    }
            }
        }
        private void this_GadgetDragEnter(GadgetWindow gadget)
        {
        }
        private void this_GadgetDragLeave(GadgetWindow gadget)
        {
            this.dock.Fill();
        }
        private void this_GadgetDragOver(GadgetWindow gadget)
        {
            this.dock.ClearPlaceFor(gadget);
        }
        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //ReleaseCapture();

            //SendMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
        }
        private void Window1_MouseEnter(object sender, MouseEventArgs e)
        {
            this.Active = true;
        }
        private void Window1_MouseLeave(object sender, MouseEventArgs e)
        {
            this.Active = false;
        }
        private void Window1_MouseMove(object sender, MouseEventArgs e)
        {
            Point position = e.GetPosition(this);
            if (position.X <= 5.0)
            {
                base.Cursor = Cursors.SizeWE;
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    NativeMethods.SendMessage(this.Handle, 0x112, 0xf001, IntPtr.Zero);
                }
            }
            else
            {
                base.Cursor = Cursors.Arrow;
            }
        }
        private void Window1_Closing(Object sender, CancelEventArgs e)
        {
            CloseChildWindows();
        }
        private void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            ShowChildWindows();
        }
        private void ExitContextMenu_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void AddGadgetContextMenu_Click(object sender, RoutedEventArgs e)
        {
            addGadgetWindow.RefreshGadgetList();
            addGadgetWindow.Show();
        }

        protected virtual void OnGadgetDragEnter(GadgetWindow gadget)
        {
            if (GadgetDragEnter != null)
            {
                GadgetDragEnter(gadget);
            }
        }
        protected virtual void OnGadgetDragLeave(GadgetWindow gadget)
        {
            if (GadgetDragLeave != null)
            {
                GadgetDragLeave(gadget);
            }
        }
        protected virtual void OnGadgetDragOver(GadgetWindow gadget)
        {
            if (GadgetDragOver != null)
            {
                GadgetDragOver(gadget);
            }
        }
        protected virtual void OnGadgetDrop(GadgetWindow gadget)
        {
            this.dock.Insert(this.dock.GetPlaceIndex(gadget), gadget);
        }


        private BitmapImage GetBitmapImage(string localPath)
        {
            return GlobalMethods.GetBitmapImage(GlobalMethods.GetFullPath(localPath));
        }

    }
}


 

 
